#!/usr/bin/python3
import os
import json
import random
from concurrent import futures
from concurrent.futures import ThreadPoolExecutor
from .httprequest import get
from .constant import DEFAULT_SAVE_PATH


class GiteeAPI:
    """
    gitee api
    """

    @get
    def issue_by_pr(self, issue, **kwargs):
        """
        根据issue获取patch
        """
        issue_pr_url = "https://gitee.com/api/v5/repos/open_euler/issues/{}/pull_requests".format(
            issue)
        return issue_pr_url

    @get
    def commit_to_patch(self, pkg_name, number, **kwargs):
        """
        根据commit获取patch
        """
        commit_patch_url = "https://gitee.com/api/v5/repos/src-openeuler/{}/pulls/{}/files".format(
            pkg_name, number)
        return commit_patch_url


class DownloadGiteePatch:
    """
    download patch file
    """
    # TODO 优化的改进项
    access_token = [
        "0327d101edfb8cffb142efeaecb578ef"
    ]
    pool = ThreadPoolExecutor(max_workers=20)

    def __init__(self, cve, issue_id):
        self.cve = cve
        self.issue = issue_id
        self.gitee_api = GiteeAPI()

    @property
    def get_issue(self):
        static_code, response = self.gitee_api.issue_by_pr(
            issue=self.issue, params={"access_token": self.access_token[random.randint(0, len(self.access_token) - 1)]})

        if static_code != 200:
            return []
        try:
            response = json.loads(response)
        except json.JSONDecodeError:
            response = list()
        return response

    def get_patch(self, pkg_name, number):
        static_code, response = self.gitee_api.commit_to_patch(pkg_name, number, params={
            "access_token": self.access_token[random.randint(0, len(self.access_token) - 1)]})

        if static_code != 200:
            return []
        try:
            response = json.loads(response)
        except json.JSONDecodeError:
            response = list()
        return response

    def _parse_issue(self, issue_info):

        issue_list = list()
        patch_urls = list()
        for issue in issue_info:
            try:
                patch_data = self.get_patch(
                    issue["head"]["repo"]["name"], issue["number"])
                for patch_url in patch_data:
                    patch_urls.append({"filename": patch_url["filename"],
                                       "raw_url": patch_url["raw_url"]})
                issue_list.append({
                    "label": issue["base"]["label"],
                    "name": issue["head"]["repo"]["name"],
                    "patch_url": patch_urls
                })
            except (TypeError, KeyError):
                pass

        return issue_list

    @get
    def _download(self, patch_url):
        return patch_url

    def download_patch(self):
        """
        patch file download
        """

        issues = self._parse_issue(self.get_issue)
        tasks = [self.pool.submit(self._save_patch, issue) for issue in issues]
        futures.as_completed(tasks)

    def _save_patch(self, url):

        pkg_name = url.get("name")
        branch = url.get("label")
        _path = os.path.join(
            DEFAULT_SAVE_PATH, pkg_name + "-" + self.cve, branch)
        patch_url = url.get("patch_url")
        for raw_url in patch_url:
            status_code, response = self._download(
                patch_url=raw_url.get("raw_url"))
            # if status_code != 200:
            #     save_file(path=os.path.join(_path, "download_fail.txt"), content="未能正确下载patch文件：%s" %
            #                                                                      patch_url)
            # save_file(path=os.path.join(
            #     _path, raw_url.get("filename")), content=response)
